package com.example.controller;

import com.example.anno.CheckRepeat;
import com.example.constants.RabbitConts;
import com.example.dao.DiscussDao;
import com.example.dao.IcommentDao;
import com.example.dao.UserInfoDao;
import com.example.model.pojo.*;
import com.example.model.vo.*;
import com.example.service.UserInfoService;
import com.example.untils.EmailUntil;
import com.example.untils.SMSUtil;
import com.example.untils.JJWTUntil;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("user")
public class UserInfoController {
    @Autowired
    private NiuMaBean niuMaBean;
    @Autowired
    private UserInfoDao userInfoDao;
    @Autowired
    private EmailUntil emailUntil;
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private BCryptPasswordEncoder passwordEncoder;
    @Autowired
    private SMSUtil smsUtil;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private IcommentDao icommentDao;

    @Autowired
    private DiscussDao discussDao;

    @PostMapping("vip")
    public  Result openVips(HttpServletRequest request)
    {
        UserInfo userInfo= (UserInfo) request.getAttribute("userInfo");
        Integer uuid=userInfo.getUuid();
        String content=userInfoService.openVip(uuid);
        if(content.equals("error"))
        {
            return new Result("400","您已经是会员了");
        }
        else
        {
            return  new Result("200","success",content);
        }


    }

    @PostMapping("not")
    public  void  notifys(HttpServletRequest request)
    {
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }

        params.forEach((k,v)->{
            System.out.println(k+":"+v);
        });
    }


    @CheckRepeat(save = true)
    @GetMapping("getToken")
    public Result getToken(HttpServletRequest request)
    {
        String repeatToken= (String) request.getAttribute("repeatToken");
        return  new Result("200","success",repeatToken);
    }



    @CheckRepeat(repeat = true)
    @GetMapping("email")
    public Result getEmail(String email)
    {
        //效验数据
        if(email==null || email.length()==0)
            return  new Result("401","邮箱为空");
        UserInfo userInfo=userInfoDao.getByEmail(email);
        if(userInfo==null)
            return new Result("401","邮箱错误");

        //生成验证码
        Integer code=emailUntil.GCode();

        //用codeVo封装code和email
        CodeVo codeVo=new CodeVo(code.toString(),userInfo.getEmail());
        //codeVo存储在redis
        redisTemplate.opsForValue().set(codeVo.getEmail(),codeVo,1,TimeUnit.MINUTES);

        //异步投递消息
        rabbitTemplate.convertAndSend(RabbitConts.EMAIL_QUEUES,codeVo);

        return  new Result("200","验证码已发送至邮箱，请稍后");
    }


    @GetMapping("login")
    public Result login(@Valid CodeVo codeVo, BindingResult bindingResult)
    {
        //效验器验证参数
        List<FieldError> errorList = bindingResult.getFieldErrors();
        Map<String, String> maps = new HashMap<>();
        for (FieldError fieldError : errorList) {
            maps.put(fieldError.getField(), fieldError.getDefaultMessage());
        }
        if (errorList.size() > 0) {
            return new Result("401", maps);
        }

        CodeVo codeVo1 = (CodeVo) redisTemplate.opsForValue().get(codeVo.getEmail());
        if(codeVo1==null) {
            return new Result("401", "验证码错误");
        }
        String code1=codeVo1.getCode();
        if(code1.equals(codeVo.getCode())) {
            UserInfo userInfo=userInfoDao.getByEmail(codeVo.getEmail());
            String token= JJWTUntil.geneJsonWebToken(userInfo);
            return new Result("200", "登录成功",token);
        }
        else {
            return new Result("401", "验证码错误");
        }
    }

    @CheckRepeat(repeat = true)
    @GetMapping("phone")
    public Result getPhone(String phone){
        /**
        * @Description :手机号码获取
        * @Author : 27954
        * @Date: 2022/9/15 18:23
        */
        //校验数据
        if (phone==null || phone.length()==0){
            return new Result("401","手机号为空");
        }
        UserInfo userInfo=userInfoDao.getByPhone(phone);
        if (userInfo==null){
            return new Result("401","手机号不存在");
        }
        if (!phone.equals(niuMaBean.getPhone())){
            return new Result("401","手机号未开启验证登录");
        }
        //生成验证码并封装在PCodeVo
        Integer code= smsUtil.GCode();
        PCodeVo pCodeVo=new PCodeVo(code.toString(),userInfo.getPhone());
        System.out.println(code);
        //将pCodeVo存储在redis
        redisTemplate.opsForValue().set(pCodeVo.getPhone(),pCodeVo,2,TimeUnit.MINUTES);
        //异步投递消息
        rabbitTemplate.convertAndSend(RabbitConts.PHONE_QUEUES,pCodeVo);
        return  new Result("200","验证码已发送至手机，请稍后",code);
    }


    @GetMapping("plogin")
    public Result plogin(@Valid PCodeVo pCodeVo,BindingResult bindingResult){
        //校验器验证参数
        
        List<FieldError> errorList =bindingResult.getFieldErrors();
        Map<String,String>map=new HashMap<>();
        for (FieldError fieldError :errorList){
            map.put(fieldError.getField(),fieldError.getDefaultMessage());
        }
        if (errorList.size()>0){
            return new Result("401",map);
        }
        PCodeVo pCodeVo1= (PCodeVo) redisTemplate.opsForValue().get(pCodeVo.getPhone());

        if (pCodeVo1==null){
            return new Result("401","验证码过期或未获取");
        }
        String code1=pCodeVo1.getCode();
        if (code1.equals(pCodeVo.getCode())){
            UserInfo userInfo=userInfoDao.getByPhone(pCodeVo.getPhone());
            String token= JJWTUntil.geneJsonWebToken(userInfo);
            return new Result("200","登录成功",token);
        }
        else {
            return new Result("401","验证码有误");
        }
    }

    @GetMapping("ulogin")
    public Result ulogin(@Valid UVo uVo,BindingResult bindingResult){
        //校验器验证参数
        List<FieldError> errorList =bindingResult.getFieldErrors();
        Map<String,String>map=new HashMap<>();
        for (FieldError fieldError :errorList){
            map.put(fieldError.getField(),fieldError.getDefaultMessage());
        }
        if (errorList.size()>0){
            return new Result("401",map);
        }
        String nickname=uVo.getNickname();
        UVo uVo1=userInfoService.ulogin(nickname);
        if (uVo1==null){
            return new Result("401","用户名或密码错误");
        }
        if (passwordEncoder.matches(uVo.getPassword(),uVo1.getPassword())){
            UserInfo userInfo=userInfoDao.getByNickname(uVo.getNickname());
            String token= JJWTUntil.geneJsonWebToken(userInfo);
            return new Result("200","登录成功",token);
        }else {
            return new Result("401","用户名或密码错误");
        }
    }

    @GetMapping("userinfo")
    public  Result getInfo(HttpServletRequest request)
    {
        UserInfo userInfo= (UserInfo) request.getAttribute("userInfo");
        List<CommentOneVo> list=new ArrayList<>();
        List<Discussion > discussions=discussDao.findAllByUid(userInfo.getUuid());
        Integer counts=0;
        for (Discussion discussion : discussions) {
            Integer disId=discussion.getId();
            List<Comment> comments=icommentDao.findAllByDiscussId(disId);
            counts+=comments.size();
            for (Comment comment : comments) {
                CommentOneVo commentOneVo=new CommentOneVo();
                 UserInfo userInfo1=userInfoDao.getByUuid( comment.getUuId());
                commentOneVo.setContent(comment.getContent());
                if(null!=userInfo1)
                commentOneVo.setCavatar(userInfo1.getAvatar());
                list.add(commentOneVo);
            }
        }

        UserInfo userInfo1=userInfoDao.getByUuid(userInfo.getUuid());

        UserVo userVo=new UserVo(userInfo.getNickname(),userInfo.getAvatar(),list,counts,userInfo1.getIsvip());
        return  new Result("200",userInfo.getUuid()+"",userVo);
    }

    @PostMapping("upimg")
    public  Result upImg(MultipartFile file) throws IOException {
        String fileName=file.getOriginalFilename();
        String result= UUID.randomUUID().toString()+fileName;
        File file1=new File("D:\\nginx-1.22.0\\nginx-1.22.0\\html\\cattle-and-horses-oj-html\\image\\"+result);
        file.transferTo(file1);
        return new Result("200", "success", result);
    }

    @PostMapping("register")
    public  Result register(@Valid UserInfo userInfo,BindingResult result)
    {
        List<FieldError> fieldErrorList=result.getFieldErrors();
        Map<String,String> maps=new HashMap<>();
        for (FieldError fieldError : fieldErrorList) {
            maps.put(fieldError.getField(),fieldError.getDefaultMessage());
        }
        if(maps.size()>0)
        {
            return  new Result("400","验证失败",maps);
        }
        String pwd= passwordEncoder.encode(userInfo.getPassword());
        userInfo.setPassword(pwd);
        userInfoDao.save(userInfo);
        return  new Result("200","success","注册成功");
    }
}
